import greenfoot.*;  // (World, Actor, GreenfootImage, Greenfoot and MouseInfo)
import java.util.*;
/**
 *El mundo es donde se concentra las condiciones del juego 
 *y como actuara
 * @author (Roberto Rodrguez) 
 * @version (27-may-2012)
 */
public class WorldGather extends World
{
    private int ataque;                     //Indica cuandos acaques ha recibido el jugador esto para la reduccion de la barra
    private int iFondo;                     //Es el iterador para que el fondo cambie siempre y cuando la posicion del heroe sea derecha
    private int nivel;                      //Indica el nivel en el que se encuentra para saber que fondo es el que cambiara y como saldran los malosos
    private int contador;                   //Es el timpo que indica que cada 30 actuas entra al cambo de fondo
    private int vidas;                      //Son la vidas del heroe
    private int barraVida;                  //Indica que barra de vida se encuentra
    private int monedas;                    //Indica las monedas que se estan obteniendo
    private int nJugador;                   //Indica el numero de jugador para saber que vehiculo tiene el jugador
    private int monedasDeCambio;            //Indica cuantas monedas debe agarrar para que el jugador cambie de vehiculo
    private Contador contadorVidas;         //Es el contador de vida que esta incertado en la pantalla
    private Contador contadorMonedas;       //Es el contador de monedas que esta en la pantalla
    private int posMundo;                   //posicion del heroe en el mundo
    private static final int izquierda = 1; //Constante izquierda para detener el avance de fondo
    private static final int derecha = 0;   //Constante derecha para que avance el fondo
    /**
     * Constructor del Mundo solamente hace inicializacion de las variables
     */
    public WorldGather()
    {    
        super(731, 548, 1);     //Establece el tamaño del mundo
        barraVida=8;            //Indica que barra de vida se encuentra
        monedasDeCambio=0;      //Indica cuantas monedas debe agarrar para que el jugador cambie de vehiculo
        vidas=3;                //Son la vidas del heroe
        monedas=0;              //Indica las monedas que se estan obteniendo
        iFondo=1;               //Es el iterador para que el fondo cambie siempre y cuando la posicion del heroe sea derecha
        contador=0;             //Es el timpo que indica que cada 30 actuas entra al cambo de fondo
        nivel=0;                //Indica el nivel en el que se encuentra para saber que fondo es el que cambiara y como saldran los malosos
        nJugador=1;             //Indica el numero de jugador para saber que vehiculo tiene el jugador
        menu();                 //Hace el llamado del metodo Menu()
    }
    /**
     * Se ejecutan constantemente mientas el boton de run este precionado
     */
    public void act()
    {
        juega();//Hace llamado del metodo juega()
    }
    /**
     * Este metodo es el que hace que el fondo cambie ademas de que genera los enemigos y las monedas
     */
    public void juega()
    {
        if(nivel!=0)
        {
            contador++;
            if(contador==30)
            {
                if(iFondo<9 && posMundo==derecha){
                    contador=0;
                    setBackground("nivel"+nivel+iFondo+".jpg");//concatenacion para evitar mas asiganciones
                    iFondo++;
                }else
                {
                    iFondo=1;
                    contador=0;
                }
                generaMoneda(); 
                if(iFondo>8)
                    generaEnemigo();
            }
         }
    }
    /**
     * Este metodo es el que cambia la variable posMundo 
     * que hace que el cambie la imagen de fondo o no dependiendo de la orientacion del heroe en el mundo
     * @param entero de la posicion que va a cambiar
     */
    public void cambiaPosicion(int pos)
    {
        posMundo=pos;   //asignacion
    }
    /**
     * En este metodo mediante un random dependiendo del nivel
     * gerena que tipo de enemigo va a poner si es un enemigo Horizontal o enemigo Vertical
     */
    public void generaEnemigo()
    {
        int num;
        if(nivel==1)
            num=Greenfoot.getRandomNumber(5);
        else
             num=Greenfoot.getRandomNumber(2);
             
        EnemigoV enemigo = new EnemigoV(nivel);     //Se hace la asiganacion con el nivel en que se encuentra
        EnemigoH enemigo1 = new EnemigoH(nivel);    //Se hace la asiganacion con el nivel en que se encuentra
        if(num==0)  
                       addObject(enemigo, 715, 389);
                else
                    if(num==1)
                       addObject(enemigo1, 715, 389);
       
    }
    /**
     * En este metodo mediante un ramdon dependiendo del nivel
     * genera monedas en posicion distinta y a una velocidad de aparicion diferente.
     */
    public void generaMoneda()
    {
        int num;
        if(nivel==1)
            num=Greenfoot.getRandomNumber(9);
        else
             num=Greenfoot.getRandomNumber(5);
        Moneda m= new Moneda();
        if(num==1)
                    addObject(m, 715, 389);
                else
                    if(num==2)
                        addObject(m, 715, 254);
    }
    /**
     * Este metodo borra y hace las asignaciones necesarias para ejecutar el nivel 3
     */
    public void nivel3()
    {
        List listaHeroe = super.getObjects(Heroe.class);
        super.removeObjects(listaHeroe);
        List listaMoneda = super.getObjects(Moneda.class);
        super.removeObjects(listaMoneda);
        List listaEnemigos = super.getObjects(Enemigos.class);
        super.removeObjects(listaEnemigos);
        setBackground("nivel31.jpg");
        monedas=0;
        contadorMonedas.actualizaValor(monedas);
        monedasDeCambio=80;
        ataque=0;
        nivel=3;
        nJugador=6;
        Heroe h= new Heroe(nJugador);
        addObject(h,100,384);
    }
    /**
     * Este metodo borra y hace las asignaciones necesarias para ejecutar el nivel 3
     */
    public void nivel2()
    {
        List listaHeroe = super.getObjects(Heroe.class);
        super.removeObjects(listaHeroe);
        List listaMoneda = super.getObjects(Moneda.class);
        super.removeObjects(listaMoneda);
        List listaEnemigos = super.getObjects(Enemigos.class);
        super.removeObjects(listaEnemigos);
        setBackground("nivel21.jpg");
        monedas=0;
        contadorMonedas.actualizaValor(monedas);
        monedasDeCambio=60;
        ataque=0;
        nivel=2;
        nJugador=4;
        Heroe h= new Heroe(nJugador);
        addObject(h,100,384);
    }
    /**
     * El metodo que primero se genera nivel1 en este metodo crea la barra los letreros y contadores ademas
     * que hace las asignaciones necesarias para empezar a ejecutar el juego
     */
    public void nivel1()
    {
        setBackground("nivel11.jpg");
        vidas=3;
        Barra b = new Barra(barraVida);
        addObject(b, 367, 48);
        Button letreroV = new Button(5);
        addObject(letreroV, 45, 31);
        contadorVidas = new Contador();
        addObject(contadorVidas, 78, 51);
        contadorVidas.actualizaValor(vidas);
        Button letrero = new Button(4);
        addObject(letrero, 691, 35);
        contadorMonedas = new Contador();
        addObject(contadorMonedas, 709, 54);
        Heroe h= new Heroe(nJugador);
        addObject(h,100,384);
        nivel=1;
        monedasDeCambio=30;
        ataque=0;
    }
    /**
     * Este metodo dependiendo del nivel que se encuentre hace el cambio de vehiculo del heroe en el mundo
     * @param entero x de la posicion actual del heroe para poner el nuevo en esa posicion
     * @param entero y de la pisicion actual del heroe para poner el nuevo en esa posicion
     */
    public void cambiaHeroe(int x, int y)
    {
        if(nivel==1 && nJugador!=3)
        {
            List listaHeroe = super.getObjects(Heroe.class);
            super.removeObjects(listaHeroe);
            nJugador++;
            Heroe h= new Heroe(nJugador);
            addObject(h,x,384);
            monedasDeCambio+=monedasDeCambio;
            ataque=0;
        }
        if(nivel==2 && nJugador!=5)
        {
            List listaHeroe = super.getObjects(Heroe.class);
            super.removeObjects(listaHeroe);
            nJugador++;
            Heroe h= new Heroe(nJugador);
            addObject(h,x,384);
            monedasDeCambio+=monedasDeCambio;
            ataque=0;
        } 
        if(nivel==3 && nJugador!=7)
        {
            List listaHeroe = super.getObjects(Heroe.class);
            super.removeObjects(listaHeroe);
            nJugador++;
            Heroe h= new Heroe(nJugador);
            addObject(h,x,384);
            monedasDeCambio+=monedasDeCambio;
            ataque=0;
        }
    }
    /**
     * Este metodo cada que agarra una moneda la contabiliza
     * este metodo a su vez hace el llamado del metodo cambia hereo por lo tanto es delegado de las coordenadas
     * @param entero x de la posicion actual del heroe para poner el nuevo en esa posicion
     * @param entero y de la pisicion actual del heroe para poner el nuevo en esa posicion 
     */
    public void aumentaMonedas(int x, int y)
    {
        monedas++;
        contadorMonedas.actualizaValor(monedas);
        if(monedas==monedasDeCambio){
            this.cambiaHeroe(x,y);
        }
        if(monedas==100)
            cambiaNivel();
         
    }
    /**
     * Este metodo es para cambiar de nivel del juego
     * y si esta en el ultimo nivel reinicia el juego y muestra el menu
     */
    public void cambiaNivel()
    {
        switch(nivel)
        {
            case 1: nivel2();
                break;
            case 2: nivel3();
                break;
            case 3:
                    barraVida=8;
                    monedasDeCambio=0;
                    vidas=3;
                    monedas=0;
                    iFondo=1;
                    contador=0;
                    nivel=0;
                    nJugador=1;
            
                    List listaHeroe = super.getObjects(Heroe.class);
                    super.removeObjects(listaHeroe);
                    List listaMoneda = super.getObjects(Moneda.class);
                    super.removeObjects(listaMoneda);
                    List listaEnemigos = super.getObjects(Enemigos.class);
                    super.removeObjects(listaEnemigos);
            
                    Button m = new Button(6);
                    addObject(m,200,200);
                 break;
        }
    }
    /**
     * Este metodo es utilizado disminuye las vidas y actializa el contador
     * ademas si al disminuir la vida es la ultima que tenia marca el final
     * del juego y reinicia el juego
     */
    public void disminuyeVidas()
    {
        vidas--;
        contadorVidas.actualizaValor(vidas);
        if(vidas<=0){
            barraVida=8;
            monedasDeCambio=0;
            vidas=3;
            monedas=0;
            iFondo=1;
            contador=0;
            nivel=0;
            nJugador=1;
            
            List listaHeroe = super.getObjects(Heroe.class);
            super.removeObjects(listaHeroe);
            List listaMoneda = super.getObjects(Moneda.class);
            super.removeObjects(listaMoneda);
            List listaEnemigos = super.getObjects(Enemigos.class);
            super.removeObjects(listaEnemigos);
            
            Button m = new Button(7);
            addObject(m,200,200);
        }
    }
    /**
     * Este metodo hace el cambio de imagenes llamadas barra que indica la barra de la vida
     * del heroe si funcion es borra la barra actual y aumenta contadoe de barra y pone la nueva
     * @param entero de la inmunidad del vehiculo en el que se encuentra el heroe
     */
    public void disminuyeBarra(int inmu)
    {
        ataque++;
        if(ataque==inmu) //checa si el numero de ataque es igual a la inmunidad que tiene el heroe
        {
            List listaBarra = super.getObjects(Barra.class);
            super.removeObjects(listaBarra);
            if(barraVida>0)
            {
                barraVida--;
                Barra b = new Barra(barraVida);
                addObject(b, 367, 48);
            }
            if(barraVida<=0)
            {
                barraVida=8;
                disminuyeVidas();
                Barra b = new Barra(barraVida);
                addObject(b, 367, 48);
            }
            ataque=0;
        }
    }
    /**
     * Este metodo pone los botones iniciales del menu
     */
    public void menu()
    {
        clearObjects();
        setBackground("Menu.jpg");
        Button b = new Button(1);
        Button b1 = new Button(2);
        Button b2 = new Button(3);
        addObject(b,420,278);
        addObject(b1,384,368);
        addObject(b2,335,450);
    }
    /**
     * Este metodo pone la imagen del primer tutorial
     * y los botones de anterior y siguiente
     */
    public void tutorial()
    {
        setBackground("tutorial1.jpg");
        Button ant = new Button(8);
        Button sig = new Button(9);
        addObject(ant,37,475);
        addObject(sig,666,481);
    }
    /**
     * Este metodo pone la imagen del segundo tutorial
     * y los botones de anterior y siguiente
     */
    public void tutorial2()
    {
        setBackground("tutorial2.jpg");
        Button ant = new Button(10);
        Button sig = new Button(11);
        addObject(ant,37,475);
        addObject(sig,666,481);
    }
    /**
     * Este metodo pone la imagen del tercer tutorial
     * y el boton de anterior.
     */
    public void tutorial3()
    {
        setBackground("tutorial3.jpg");
        Button ant = new Button(12);
        addObject(ant,37,475);
    }
    /**
     * Este metodo pone la imagen de los creditos
     * y el boton de anterior.
     */
    public void creditos()
    {
        setBackground("Creditos.jpg");
        Button ant = new Button(13);
        addObject(ant,37,475);
    }
    /**
     * Este metodo borra todos los objetos del mundo
     */
    public void clearObjects(){
    removeObjects(getObjects(null));}
}
